package io.terminus.lego.shinda.web.security.special_user.configure

import io.terminus.lego.shinda.web.security.special_user.filter.SpecialUserAuthenticationProcessingFilter
import io.terminus.lego.shinda.web.security.special_user.provider.SpecialUserAuthenticationProvider
import org.springframework.security.config.annotation.web.HttpSecurityBuilder
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer
import org.springframework.security.web.authentication.ForwardAuthenticationFailureHandler
import org.springframework.security.web.authentication.ForwardAuthenticationSuccessHandler
import org.springframework.security.web.util.matcher.AntPathRequestMatcher
import org.springframework.security.web.util.matcher.RequestMatcher

/**
 *特殊用户登录功能配置类
 * @author 王猛
 * @date 2018/4/28
 */
class SpecialUserLoginConfigurer<H : HttpSecurityBuilder<H>> constructor(filter: SpecialUserAuthenticationProcessingFilter,
                                                                         val provider: SpecialUserAuthenticationProvider) :
        AbstractAuthenticationFilterConfigurer<H, SpecialUserLoginConfigurer<H>, SpecialUserAuthenticationProcessingFilter>(filter, null) {
    /**
     * Creates a new instance
     * @see HttpSecurity.formLogin
     */
    init {
        usernameParameter(usernameParameter)
        passwordParameter(passwordParameter)
        userTypeParameter(userTypeParameter)
    }

    /**
     *
     */
    public override fun loginPage(loginPage: String): SpecialUserLoginConfigurer<H> {
        return super.loginPage(loginPage)
    }

    /**
     * The HTTP parameter to look for the username when performing authentication. Default
     * is "username".

     * @param phoneParameter the HTTP parameter to look for the username when
     * * performing authentication
     * *
     * @return the [SpecialUserLoginConfigurer] for additional customization
     */
    fun usernameParameter(usernameParameter: String): SpecialUserLoginConfigurer<H> {
        authenticationFilter.PARAMTER_KEY_USERNAME = usernameParameter
        return this
    }

    /**
     * The HTTP parameter to look for the password when performing authentication. Default
     * is "password".

     * @param passwordParameter the HTTP parameter to look for the password when
     * * performing authentication
     * *
     * @return the [SpecialUserLoginConfigurer] for additional customization
     */
    fun passwordParameter(passwordParameter: String): SpecialUserLoginConfigurer<H> {
        authenticationFilter.PARAMTER_KEY_PASSWORD = passwordParameter
        return this
    }


    /**
     * The HTTP parameter to look for the user_type when performing authentication. Default
     * is "user_type".

     * @param userTypeParameter the HTTP parameter to look for the user_type when
     * * performing authentication
     * *
     * @return the [SpecialUserLoginConfigurer] for additional customization
     */
    fun userTypeParameter(userTypeParameter: String): SpecialUserLoginConfigurer<H> {
        authenticationFilter.PARAMTER_KEY_USERTYPE = userTypeParameter
        return this
    }

    /**
     * Forward Authentication Failure Handler

     * @param forwardUrl the target URL in case of failure
     * *
     * @return the [SpecialUserLoginConfigurer] for additional customization
     */
    fun failureForwardUrl(forwardUrl: String): SpecialUserLoginConfigurer<H> {
        failureHandler(ForwardAuthenticationFailureHandler(forwardUrl))
        return this
    }

    /**
     * Forward Authentication Success Handler

     * @param forwardUrl the target URL in case of success
     * *
     * @return the [SpecialUserLoginConfigurer] for additional customization
     */
    fun successForwardUrl(forwardUrl: String): SpecialUserLoginConfigurer<H> {
        successHandler(ForwardAuthenticationSuccessHandler(forwardUrl))
        return this
    }

    @Throws(Exception::class)
    override fun init(http: H) {
        super.init(http)
        http.authenticationProvider(provider)
    }

    /*
	 * (non-Javadoc)
	 *
	 * @see org.springframework.security.config.annotation.web.configurers.
	 * AbstractAuthenticationFilterConfigurer
	 * #createLoginProcessingUrlMatcher(java.lang.String)
	 */
    override fun createLoginProcessingUrlMatcher(loginProcessingUrl: String): RequestMatcher {
        return AntPathRequestMatcher(loginProcessingUrl, "POST")
    }

    /**
     * Gets the HTTP parameter that is used to submit the username.

     * @return the HTTP parameter that is used to submit the username
     */
    private val usernameParameter: String
        get() = authenticationFilter.PARAMTER_KEY_USERNAME

    /**
     * Gets the HTTP parameter that is used to submit the password.

     * @return the HTTP parameter that is used to submit the password
     */
    private val passwordParameter: String
        get() = authenticationFilter.PARAMTER_KEY_PASSWORD

    /**
     * Gets the HTTP parameter that is used to submit the user_type.

     * @return the HTTP parameter that is used to submit the user_type
     */
    private val userTypeParameter: String
        get() = authenticationFilter.PARAMTER_KEY_USERTYPE


}
